//---------------------------------------------------------------------
//
//---------------------------------------------------------------------

abstract class STO
{
	private String m_strName;
	private Type m_type;
	private boolean m_isAddressable;
	private boolean m_isModifiable;
	private String base;
	private String offset;
	private boolean isGlobal;
	private String structName;
	private boolean isRef;
	private boolean isAddressOfTypeCast;

	//----------------------------------------------------------------
	//
	//----------------------------------------------------------------
	public STO(String strName)
	{
		this(strName, null);
	}

	//----------------------------------------------------------------
	//
	//----------------------------------------------------------------
	public STO(String strName, Type typ)
	{
		setName(strName);
		setType(typ);
		setIsAddressable(false);
		setIsModifiable(false);
	}

	//----------------------------------------------------------------
	//
	//----------------------------------------------------------------
	public String getName()
	{
		return m_strName;
	}

	//----------------------------------------------------------------
	//
	//----------------------------------------------------------------
	public void setName(String str)
	{
		m_strName = str;
	}

	//----------------------------------------------------------------
	//
	//----------------------------------------------------------------
	public Type getType()
	{
		return m_type;
	}

	//----------------------------------------------------------------
	//
	//----------------------------------------------------------------
	protected void setType(Type type)
	{
		m_type = type;
	}

	//----------------------------------------------------------------
	// Addressable refers to if the object has an address. Variables
	// and declared constants have an address, whereas results from 
	// expression like (x + y) and literal constants like 77 do not 
	// have an address.
	//----------------------------------------------------------------
	public boolean isAddressable()
	{
		return m_isAddressable;
	}

	//----------------------------------------------------------------
	// Check 2: Changed private to protected
	//----------------------------------------------------------------
	protected void setIsAddressable(boolean addressable)
	{
		m_isAddressable = addressable;
	}

	//----------------------------------------------------------------
	// You shouldn't need to use these two routines directly
	//----------------------------------------------------------------
	private boolean isModifiable()
	{
		return m_isModifiable;
	}

	//----------------------------------------------------------------
	// Check 2: Changed private to protected
	//----------------------------------------------------------------
	private void setIsModifiable(boolean modifiable)
	{
		m_isModifiable = modifiable;
	}

	//----------------------------------------------------------------
	// A modifiable L-value is an object that is both addressable and
	// modifiable. Objects like constants are not modifiable, so they 
	// are not modifiable L-values.
	//----------------------------------------------------------------
	public boolean isModLValue()
	{
		return isModifiable() && isAddressable();
	}
	
	public boolean isRValue() {
		boolean isMod = isModifiable();
		boolean isAddr = isAddressable();
		if(!isMod && !isAddr) {
			return true;
		}
		return false;
	}

	//----------------------------------------------------------------
	//
	//----------------------------------------------------------------
	protected void setIsModLValue()
	{
		setIsModifiable(true);
		setIsAddressable(true);
	}
	
	protected void setIsNonModLValue()
	{
		setIsModifiable(false);
		setIsAddressable(true);
	}
	
	protected void setIsRValue() {
		setIsModifiable(false);
		setIsAddressable(false);
	}

	public String getBase() {
		return base;
	}

	public void setBase(String base) {
		this.base = base;
	}

	public String getOffset() {
		return offset;
	}

	public void setOffset(String offset) {
		this.offset = offset;
	}
	
	public String getAddress() {
		return getBase() + getOffset();
	}

	//----------------------------------------------------------------
	//	It will be helpful to ask a STO what specific STO it is.
	//	The Java operator instanceof will do this, but these methods 
	//	will allow more flexibility (ErrorSTO is an example of the
	//	flexibility needed).
	//----------------------------------------------------------------
	public boolean isVar() { return false; }
	public boolean isConst() { return false; }
	public boolean isExpr() { return false; }
	public boolean isFunc() { return false; }
	public boolean isTypedef() { return false; }
	public boolean isError() { return false; }
	public boolean isArray(){return false;}

	public boolean isGlobal() {
		return isGlobal;
	}

	public void setGlobal(boolean isGlobal) {
		this.isGlobal = isGlobal;
	}

	public boolean hasAddress() {
		if(getBase() != null && getOffset() != null) {
			return true;
		}
		return false;
	}

	public String getStructName() {
		return structName;
	}

	public void setStructName(String structName) {
		this.structName = structName;
	}

	public boolean isRef() {
		return isRef;
	}

	public void setRef(boolean isRef) {
		this.isRef = isRef;
	}

	public boolean isAddressOfTypeCast() {
		return isAddressOfTypeCast;
	}

	public void setAddressOfTypeCast(boolean isAddressTypeCast) {
		this.isAddressOfTypeCast = isAddressTypeCast;
	}
}
